<?php


/** 
 * @property User_order_mdl $order 用户订单模型
 * @property Price_mdl $price 价格模型
 * @property Dev_mdl $dev 设备模型
 * @property Prepayment_log_mdl $prepaymentLog 预付款日志模型
 */
class Offline extends MY_Controller {
	
	function __construct() {
		parent::__construct();
		$this->user = parent::getLoginUser(true);
		$this->load->model('User_order_mdl','order');
		$this->load->model('Price_mdl','price');
		$this->load->model('Dev_mdl','dev');
		$this->load->model('Prepayment_log_mdl','prepaymentLog');
		
		$this->prepaymentLog->setUserID($this->user->id);
		$this->order->setUserID($this->user->id);
		
	}
	/**
	 * API:提交离线订单
	 */
	public function submit_orders_test(){
		// 处理订单
		$amountTotal = $this->handle_orders_test();
		var_dump($amountTotal);die;
		if( FALSE === $amountTotal  ){
			$this->apiOutput->errorSystem();
		}
		// 重新计算最大可离线取水时间
		// 		$maxTakeSec = $this->getMaxTakeSec($this->user->prepayment);
	
		$msg = "本次离线取水共消费:".($amountTotal/100).'元,预付款剩余:'.($this->user->prepayment/100).'元';
	
		$this->apiOutput->put('amountTotal', $amountTotal)
		->put('msg', $msg)
		->put('prepayment',$this->user->prepayment)
		->put('balance', $this->user->balance)
		->out();
	
	}
	/**
	 * 处理提交的离线订单
	 * @return int 结算总金额
	 */
	private function handle_orders_test(){
	
		$input = file_get_contents("php://input");
		debug('request',$input);
		if( empty($input) ){
			return 0;
		}
	
		$input = json_decode($input,TRUE);
		if( empty($input) ){
			$this->apiOutput->errorInput('解析JSON数据失败');
		}
	
		foreach ( array('time','orders','priceVer') as $field ){
			if( !array_key_exists($field, $input)){
				if( $field=='priceVer' ){
					$input['priceVer'] = 1;
				}else{
					$this->apiOutput->errorInput("{$field}为空");
				}
			}
		}
		if( ! is_array($input['orders']) ){
			$this->apiOutput->errorInput("orders必须为数组");
		}
		//	if( ! preg_match('/14\d{8}/', $input['time']) ){
		//			$this->apiOutput->errorInput('时间戳格式不正确');
		//	}
	
	
	
		$appTime = $input['time'];
		$orders  = $input['orders'];
		// 检查订单;过滤重复的uuid
		$orders = $this->checkOrders($orders);
		if( empty($orders) ){
			return 0;
		}
	
		// 获取订单列表中所有设备信息
		$devNames = array_column($orders, 'devName');
		$devList = array();
		if ( empty($devNames) ) {
			$this->apiOutput->errorInput('没有记录设备名称');
		}else{
			$devList = $this->dev->getListByFieldList('id,name,schoolID', 'name', $devNames);
		}
	
	
		// 水类型
		$types = array(BUY_MODE_HOT,BUY_MODE_COLD,BUY_MODE_ONCE,BUY_MODE_PULES_HOT,BUY_MODE_PULES_COLD);
		// 总水费
		$amountTotal = 0;
		// 所有待插入的订单
		$batchOrders = array();
		// 计算app时间戳与服务器时间戳误差
		$now = time();
		$diffTime = $now - $appTime;
	
		foreach ($orders as $k=>$order){
			// 			// =====================
			// 			foreach (array('devName','beginTime','type','takeSec') as $field){
			// 				if( ! array_key_exists($field, $order) ){
			// 					$this->apiOutput->errorInput("第{$k}张订单'{$field}'不存在!");
			// 				}
			// 			}// =================================
			foreach (array('devName','beginTime','type','takeSec','lon','lat') as $field){
				$order[$field] = array_key_exists($field, $order) ? $order[$field] : '';
			}
			// 			if(!empty($order['uuid'])){
			// 				$where = array('uuid'=>$order['uuid']);
			// 				$old = $this->order->getOne($where);
			// 				if(!empty($old)){
			// 					continue;
			// 				}
			// 			}
	
	
			// 获取学校ID与设备ID
			$devID = 0;
			$schoolID = 0;
			if( ! empty($devList[$order['devName']]) ){
				$devID = $devList[$order['devName']]['id'];
				$schoolID = $devList[$order['devName']]['schoolID'];
			}
			// 水类型
			$type = in_array($order['type'], $types) ? (int)$order['type'] : BUY_MODE_HOT;
			
			// 取水秒数
			$takeSec = ( int ) $order ['takeSec'];
			$takeSec = $takeSec > 0 ? $takeSec : 1;
			// 开始取水时间
			$beginTime  = (float) $order['beginTime'];
			$createTime = $beginTime + $diffTime;
			if( $createTime<=0 ){
				$createTime = $beginTime;
			}
	
			$uuid = isset($order['uuid']) ? $order['uuid'] : $this->user->id.'$'.$createTime.$now.$k.mt_rand(1111, 9999);
	
			// 计算水费
			$amount = $this->price->calculateAmount_test($takeSec, $type, $schoolID);
			var_dump($amount);
			// 计算总水费
			$amountTotal += $amount;
	
			$batchOrders[] = array (
					'devID' => $devID,
					'userID' => $this->user->id,
					'isFinish' => 1,
					'type' => $type,
					'createTime' => $beginTime,
					'updateTime' => $now,
					'takeSec' => $takeSec,
					'price' => 1,//TODO
					'schoolID'=>$schoolID,
					'amount' => $amount,
					'phoneID' => $this->user->lockedPhoneID,
					'mode'=>2,
					'lat'=>$order['lat'],
					'lon'=>$order['lon'],
					'uuid'=>$uuid,
			);
		}
		var_dump($amountTotal);die;
		// 向用户扣钱
		if( $this->user->prepayment < $amountTotal ){
			// 预支付金额如果不够,则从余额扣钱
			$diff = $amountTotal - $this->user->prepayment;
			$this->user->prepayment = 0;
			$this->user->balance -= $diff;
		}else{
			$this->user->prepayment -= $amountTotal;
		}
		$this->user->buyTotal += $amountTotal;
		if( ! $this->user->update() ){
			$this->apiOutput->errorSystem();
			return FALSE;
		}
	
		$this->prepaymentLog->buy($amountTotal);
		// 订单入库
		$this->load->model('Order_sync_queue_mdl','syncQueue');
		foreach ( $batchOrders as $order ){
			$orderID = $this->order->insert($order);
			if( empty($orderID) ) continue;
			// 记录到缓存队列
			$this->syncQueue->enqueue($orderID,$order['userID']);
		}
		return $amountTotal;
	}
	public function access(){
		$phoneID = $this->input->post_get('phoneID',TRUE);
		$amount  = (int)$this->input->post_get('amount');
		if( empty($phoneID)  ){
			$this->apiOutput->errorInput();
		}
		if( $amount < 10 ){
			$this->apiOutput->error('预付款至少0.1元',-1);
		}
		if( $this->user->balance < $amount ){
			$this->apiOutput->error('账户可用余额不足,请充值后再支付',-2);
		}
		if( ! empty($this->user->lockedPhoneID) && $this->user->lockedPhoneID !=$phoneID  ){
			$this->apiOutput->error('您已经在其他手机上离线授权,请先取消其他手机的授权!',-3);
		}
		// 向用户表扣除预付款,锁定手机
		$this->user->balance -= $amount;
		$this->user->prepayment += $amount;
		$this->user->lockedPhoneID = $phoneID;
		if( ! $this->user->update() ){
			$this->apiOutput->errorSystem();
		}
		$this->prepaymentLog->transferIn($amount);
		// 获取价格参数
		$schoolID = empty($this->user->schoolID) ? 1 : $this->user->schoolID;
		$priceParams = $this->price->getParams($schoolID);
		
		$this->apiOutput->put('priceParams',$priceParams)
						->put('prepayment',$this->user->prepayment)
						->put('balance', $this->user->balance)
						->out();
	}
	
	public function revoke_access(){
		// 处理订单
		$amountTotal = $this->handle_orders ();
		if (empty ( $amountTotal ) && $amountTotal !==0) {
			$this->apiOutput->errorSystem ();
		}
		$prepayment = $this->user->prepayment;
		// 将预付款转到可用余额,解除绑定手机
		if ($this->user->prepayment > 0) {
			$this->user->balance += $this->user->prepayment;
			$this->user->prepayment = 0;
		}
		$this->user->lockedPhoneID = NULL;
		
		if (! $this->user->update ()) {
			$this->apiOutput->errorSystem ();
		}
		
		$this->prepaymentLog->transferOut($prepayment);
		
		$this->apiOutput->put ( 'amountTotal', $amountTotal )->put ( 'balance', $this->user->balance )->out ();
	}
	/**
	 * API:提交离线订单
	 */
	public function submit_orders(){
		// 处理订单
		$amountTotal = $this->handle_orders();
		if( FALSE === $amountTotal  ){
			$this->apiOutput->errorSystem();
		}
		// 重新计算最大可离线取水时间
// 		$maxTakeSec = $this->getMaxTakeSec($this->user->prepayment);
		
		$msg = "本次离线取水共消费:".($amountTotal/100).'元,预付款剩余:'.($this->user->prepayment/100).'元';
		
		$this->apiOutput->put('amountTotal', $amountTotal)
						->put('msg', $msg)
						->put('prepayment',$this->user->prepayment)
						->put('balance', $this->user->balance)
						->out();
		
	}
	
	private function checkOrders($orders){
		$uuidSet = array_column($orders, 'uuid');
		if( empty($uuidSet) ){
			return $orders;
		}
		$list = $this->order->getListByColValues('id,uuid', 'uuid', $uuidSet);
		if( empty($list) ){
			return $orders;
		}
		$existsUuidSet = array_column($list, 'uuid');
		return array_filter($orders,function($order)use(&$existsUuidSet){
			$rest = TRUE;
			if(!empty($order['uuid'])){
				$rest =  !in_array($order['uuid'], $existsUuidSet);
				$existsUuidSet[] =$order['uuid'];
			}
			return $rest;
		});
	}
	
	/**
	 * 处理提交的离线订单
	 * @return int 结算总金额
	 */
	private function handle_orders(){
		
		// 订单入库
		$this->load->model('Order_sync_queue_mdl','syncQueue');
		$this->load->model('Order_offline_sync_queue_mdl','offlineSyncQueue');
		$this->load->model('Order_sign_log_mdl','signLog');
		$input = file_get_contents("php://input");
		
		debug('request',$input);
		if( empty($input) ){
			return 0;
		}
		
		$sign = md5($input);
		$nowtime = time();
		$etime = 60;//1分钟内不能重复提交
		
		//查询token是否存在
		$whereSign = array('sign'=>$sign);
		$check = $this->signLog->findOne($whereSign);
		
		if ( empty($check) ){
			$dataSign = array('uid'=>(int)$this->user->id,'sign'=>$sign,'state'=>0,'ctime'=>$nowtime);
			$inSign = $this->signLog->insert($dataSign);
			if ( !$inSign ){
				$this->apiOutput->errorInput('签名失败');
			}
		}else{
			
			if ( ($nowtime-$etime)>$check['ctime'] ){
				if ( $check['state'] === 1 ){
					return 0;
// 					$this->apiOutput->errorInput('本次订单已处理过');
				}
			}else{
				$this->apiOutput->errorInput('不能重复提交订单');
			}
				
		}
		
		$input = json_decode($input,TRUE);
		if( empty($input) ){
			$this->apiOutput->errorInput('解析JSON数据失败');
		}
		
		foreach ( array('time','orders','priceVer') as $field ){
			if( !array_key_exists($field, $input)){
				if( $field=='priceVer' ){
				   $input['priceVer'] = 1;	
				}else{
				   $this->apiOutput->errorInput("{$field}为空");
				}
			}
		}
		if( ! is_array($input['orders']) ){
			$this->apiOutput->errorInput("orders必须为数组");
		}
	//	if( ! preg_match('/14\d{8}/', $input['time']) ){
	//			$this->apiOutput->errorInput('时间戳格式不正确');
	//	}
		
		$appTime = $input['time'];
		$orders  = $input['orders'];
		// 检查订单;过滤重复的uuid
		$orders = $this->checkOrders($orders);
		
		if( empty($orders) ){
			return 0;
		}
		
		//过滤上传重复订单
		$orders = $this->array_unset_tt($orders, 'uuid');
		
		// 获取订单列表中所有设备信息
		$devNames = array_column($orders, 'devName');
		$devList = array();
		if ( empty($devNames) ) {
			$this->apiOutput->errorInput('没有记录设备名称');
		}else{
			$devList = $this->dev->getListByFieldList('id,name,schoolID', 'name', $devNames);
		}
		
		
		// 水类型		
		$types = array(BUY_MODE_HOT,BUY_MODE_COLD,BUY_MODE_ONCE,BUY_MODE_PULES_HOT,BUY_MODE_PULES_COLD);
		// 总水费
		$amountTotal = 0;
		// 所有待插入的订单
		$batchOrders = array();
		// 计算app时间戳与服务器时间戳误差
		$now = time();
		$diffTime = $now - $appTime;
		
		foreach ($orders as $k=>$order){
// 			// =====================
// 			foreach (array('devName','beginTime','type','takeSec') as $field){
// 				if( ! array_key_exists($field, $order) ){
// 					$this->apiOutput->errorInput("第{$k}张订单'{$field}'不存在!");
// 				}
// 			}// =================================
			foreach (array('devName','beginTime','type','takeSec','lon','lat') as $field){
				$order[$field] = array_key_exists($field, $order) ? $order[$field] : '';
			}
// 			if(!empty($order['uuid'])){
// 				$where = array('uuid'=>$order['uuid']);
// 				$old = $this->order->getOne($where);
// 				if(!empty($old)){
// 					continue;
// 				}
// 			}
			
			
			// 获取学校ID与设备ID
			$devID = 0;
			$schoolID = 0;
			if( ! empty($devList[$order['devName']]) ){
				$devID = $devList[$order['devName']]['id'];
				$schoolID = $devList[$order['devName']]['schoolID'];
			}
			// 水类型
			$type = in_array($order['type'], $types) ? (int)$order['type'] : BUY_MODE_HOT;
			// 取水秒数
			$takeSec = ( int ) $order ['takeSec'];
			$takeSec = $takeSec > 0 ? $takeSec : 1;
			// 开始取水时间
			$beginTime  = (float) $order['beginTime'];
			$createTime = $beginTime + $diffTime;
			if( $createTime<=0 ){
				$createTime = $beginTime;
			}
			
			$uuid = isset($order['uuid']) ? $order['uuid'] : $this->user->id.'$'.$createTime.$now.$k.mt_rand(1111, 9999);
			
			// 计算水费
			$amount = $this->price->calculateAmount($takeSec, $type, $schoolID);
			// 计算总水费
			$amountTotal += $amount;
			
			$batchOrders[] = array (
					'devID' => $devID,
					'userID' => $this->user->id,
					'isFinish' => 1,
					'type' => $type,
					'createTime' => $beginTime,
					'updateTime' => $now,
					'takeSec' => $takeSec,
					'price' => 1,//TODO
					'schoolID'=>$schoolID,
					'amount' => $amount,
					'phoneID' => $this->user->lockedPhoneID,
					'mode'=>2,
					'lat'=>$order['lat'],
					'lon'=>$order['lon'],
					'uuid'=>$uuid,
			);
		}
		
		// 向用户扣钱
		if( $this->user->prepayment < $amountTotal ){
			// 预支付金额如果不够,则从余额扣钱
			$diff = $amountTotal - $this->user->prepayment;
			$this->user->prepayment = 0;
			$this->user->balance -= $diff;
		}else{
			$this->user->prepayment -= $amountTotal;
		}
		$this->user->buyTotal += $amountTotal;
		if( ! $this->user->update() ){
			$this->apiOutput->errorSystem();
			return FALSE;
		}
		
		//更新签名处理成功
		$updataSign = array('$set'=>array('state'=>1,'utime'=>time()));
		$whereUpSign = array('sign'=>$sign);
		$up = $this->signLog->update($whereUpSign,$updataSign);
		
		$this->prepaymentLog->buy($amountTotal);
		
		//新:一次性存在mongo
		$res = $this->offlineSyncQueue->enqueue($batchOrders,$this->user->id);
//旧：直接插mysql		
// 		foreach ( $batchOrders as $order ){
// 			$orderID = $this->order->insert($order);
// 			if( empty($orderID) ) continue;
// 			// 记录到缓存队列
// 			$this->syncQueue->enqueue($orderID,$order['userID']);
// 		}
		return $amountTotal;
	}
	
	/**
	 * API:预付款纪录
	 */
	public function log(){
		$bottomID = ( int ) $this->input->post_get ( 'bottomID' );
		$count = ( int ) $this->input->post_get ( 'count' );
		$count = $count > 0 ? $count : 20;
		
		$where = array (
				'type !='=>'BUY',
		);
		$where ['userID'] = $this->user->id;
		if ($bottomID > 0) {
			$where ['id <'] = $bottomID;
		}
		$select = '*';
		$list = $this->prepaymentLog->getList ( $select, $where, $count, 0, 'id', 'DESC' );
		//$list=array();
		$listCount = count ( $list );
		if ($listCount < $count) {
			$hasMore = 0;
			$bottomID = 0;
		} else {
			$hasMore = 1;
			$bottomID = $list [$listCount - 1] ['id'];
		}
		$this->apiOutput->put ( 'hasMore', $hasMore )
						->put ( 'prepayment', $this->user->prepayment )
						->put ( 'bottomID', $bottomID )
						->put ( 'list', $list )
						->out ();
	}
	
	protected function array_unset_tt($arr,$key){
		//建立一个目标数组
        $res = array();      
        foreach ($arr as $value) {         
           //查看有没有重复项
           if(isset($res[$value[$key]])){
                 //有：销毁
                 unset($value[$key]);
           }else{
              $res[$value[$key]] = $value;
           }  
        }
        $res = array_values($res);
        return $res;
	}
	
	
	
	
	
	
	
}

